#pragma once


#include <limits>
#include <algorithm>
#include "math/Point.hpp"


class BoundBox
{
public:
    BoundBox() {}

    BoundBox(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax):
        xMin(xmin), xMax(xmax), yMin(ymin), yMax(ymax), zMin(zmin), zMax(zmax) {}

    BoundBox(const BoundBox& rhs):
        xMin(rhs.xMin), xMax(rhs.xMax), yMin(rhs.yMin), yMax(rhs.yMax), zMin(rhs.zMin), zMax(rhs.zMax) {}

    BoundBox& operator=(const BoundBox& rhs)
    {
        xMin = rhs.xMin;
        xMax = rhs.xMax;
        yMin = rhs.yMin;
        yMax = rhs.yMax;
        zMin = rhs.zMin;
        zMax = rhs.zMax;
        return *this;
    }

    bool isValid() const
    {
        return xMin <= xMax && yMin <= yMax && zMin <= zMax;
    }

    BoundBox operator+(const BoundBox& rhs) const
    {
        return BoundBox(std::min(xMin, rhs.xMin),
                        std::max(xMax, rhs.xMax),
                        std::min(yMin, rhs.yMin),
                        std::max(yMax, rhs.yMax),
                        std::min(zMin, rhs.zMin),
                        std::max(zMax, rhs.zMax));
    }

    BoundBox operator+(const Point& point) const
    {
        return BoundBox(std::min(xMin, point.x),
                        std::max(xMax, point.x),
                        std::min(yMin, point.y),
                        std::max(yMax, point.y),
                        std::min(zMin, point.z),
                        std::max(zMax, point.z));
    }

private:
    double xMin = std::numeric_limits<double>::max();
    double xMax = std::numeric_limits<double>::min();
    double yMin = std::numeric_limits<double>::max();
    double yMax = std::numeric_limits<double>::min();
    double zMin = std::numeric_limits<double>::max();
    double zMax = std::numeric_limits<double>::min();
};
